package server.config.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import server.dao.FrmDataResourcesDao;
import server.model.entity.Users;
import server.service.LogService;
import server.service.RedisService;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {
    @Bean
    public AutoShiro shirFilter(SecurityManager securityManager, FrmDataResourcesDao fspDataRecordDao, LogService logService, RedisService redisService) {
        System.out.println("ShiroConfiguration.shirFilter()");
        AutoShiro shiroFilterFactoryBean = new AutoShiro(fspDataRecordDao);
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/home");
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
        AuthFilter authFilter = new AuthFilter(logService, redisService);
        authFilter.setLoginUrl("/login");
        authFilter.setUsernameParam("username");
        authFilter.setPasswordParam("password");
        authFilter.setUserClass(Users.class);
        filters.put("authc", authFilter);
        SystemLogoutFilter logoutFilter = new SystemLogoutFilter(redisService);
        filters.put("loginout", logoutFilter);
        KickoutSessionControlFilter kickoutSessionControlFilter = new KickoutSessionControlFilter();
        kickoutSessionControlFilter.setCacheManager(cacheManager());
        kickoutSessionControlFilter.setSessionManager(sessionManager());
        kickoutSessionControlFilter.setKickoutUrl("login");
        filters.put("kickout", kickoutSessionControlFilter);
        shiroFilterFactoryBean.setFilters(filters);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(myShiroRealm());
        defaultSecurityManager.setSessionManager(sessionManager());
        defaultSecurityManager.setCacheManager(cacheManager());
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher("md5");
        hashedCredentialsMatcher.setHashIterations(10);
        myShiroRealm().setCredentialsMatcher(hashedCredentialsMatcher);
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        return defaultSecurityManager;
    }

    @Bean
    public UserRealm myShiroRealm() {
        return new UserRealm();
    }

    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new HeaderSessionManager();
        defaultWebSessionManager.setSessionDAO(sessionDAO());
        return defaultWebSessionManager;
    }

    @Bean
    public MemorySessionDAO sessionDAO() {
        return new MemorySessionDAO();
    }

    @Bean
    public CacheManager cacheManager() {
        return new EhCacheManager();
    }
}
